package com.java.comprehensive.arithmetic.leecode.tags.linkedlist;

import util.ListNode;

/**
 * @Author: Dgg
 * @Date: 2021/12/13 21:20
 */
public class LeetCode_203 {
	public static ListNode removeElements(ListNode head, int val) {
		if (head == null) {
			return head;
		}
		ListNode pre = new ListNode();
		/** 利用引用地址的特性 */
		pre.next = head;
		while (pre.next != null) {
			if (pre.next.val == val) {
				pre.next = pre.next.next;
			}
			if (pre.next == null) {
				break;
			}
			/** 因为修改的是pre 的引用地址 所以pre 可以 让他自己等于他下一个 来进行遍历，
			 * 当修改值的时候修改的是真正存储的head 的值达成了遍历head 修改值的目的
			 * */
			//这样写这里会产生 pre 指针指向了他自己 但是head 只想的其实是 pre.next这就不对了 应该在创建中间节点
			pre = pre.next;
		}
		return head;
	}

	public ListNode removeElementsTWO(ListNode head, int val) {
		ListNode dummyHead = new ListNode(0);
		dummyHead.next = head;
		ListNode temp = dummyHead;
		while (temp.next != null) {
			if (temp.next.val == val) {
				temp.next = temp.next.next;
			} else {
				temp = temp.next;
			}
		}
		return dummyHead.next;
	}

	public ListNode removeElementsThree(ListNode head, int val) {
		//最后的null节点在这里retun出去不影响倒数第二个
		if (head == null) {
			return head;
		}
		/** 递归找到了 最后一个节点对比最后一个节点值是否相等 一直往前推  */
		head.next = removeElements(head.next, val);
		/** 从最后比较每个 节点value 是否相等 相等的话把递归出来之前的结果指针返回*/
		return head.val == val ? head.next : head;
	}

	/** 第二轮 LeetCode目标 */

	public static void main(String[] args) {
//		ListNode listNode1 = new ListNode(6, null);
//		ListNode listNode2 = new ListNode(5, listNode1);
//		ListNode listNode3 = new ListNode(4, listNode2);
		ListNode listNode4 = new ListNode(7, null);
		ListNode listNode5 = new ListNode(7, listNode4);
		ListNode listNode6 = new ListNode(7, listNode5);
		ListNode listNode7 = new ListNode(7, listNode6);
		ListNode listNode = removeElements(listNode7, 7);
		System.out.println(listNode);
	}
}
